#pragma once
#include <cstring>
#include <mysql.h>
#include <string_view>

// Mysql mConnection C++封装

class Mysql
{
public:
	~Mysql() { Destroy(); }

	//连接
	bool Connect(std::string_view ip,
				 std::string_view user,
				 std::string_view password,
				 std::string_view db,
				 unsigned int port)
	{
		mConn = ::mysql_init(nullptr);
		if (nullptr == mConn)
			return false;

		if (!::mysql_real_connect(mConn,
								  ip.data(),
								  user.data(),
								  password.data(),
								  db.data(),
								  port,
								  nullptr,
								  0))
			return false;

		return true;
	}

	// ping
	bool Ping() { return ::mysql_ping(mConn) == 0; }

	//消毁
	bool Destroy()
	{
		if (nullptr != mConn) {
			::mysql_close(mConn);
			::mysql_stmt_close(mStmt);
			mConn = nullptr;
			mStmt = nullptr;
		}
		return true;
	}

public:
	//创建数据库或表
	bool CreateDataTable(std::string_view query)
	{
		if (::mysql_real_query(mConn,
							   query.data(),
							   static_cast<unsigned long>(query.length())))
			return false;
		return true;
	}

	//插入
	template<typename... Args>
	int Insert(std::string_view query, Args &&... args)
	{
		mStmt = ::mysql_stmt_init(mConn);
		if (!mStmt)
			return -1;

		if (::mysql_stmt_prepare(mStmt,
								 query.data(),
								 static_cast<unsigned long>(query.length())))
			return -1;

		int nCount = ::mysql_stmt_param_count(mStmt);

		MYSQL_BIND bind[3];
		std::memset(bind, 0, 3 * sizeof(MYSQL_BIND));

		if (::mysql_stmt_bind_param(mStmt, bind))
			return -1;

		if (::mysql_stmt_execute(mStmt))
			return -1;
		return 0;
	}

	// update
	template<typename... Args>
	int Update(std::string_view query, Args &&... args)
	{
		return 0;
	}

	//删除
	template<typename... Args>
	int Delete(std::string_view query, Args &&... args)
	{
		return 0;
	}

	//查询
	template<typename T, typename... Args>
	int Query(std::string_view query, const T &t, Args &&... args)
	{
		return 0;
	}

private:
	template<typename... Args>
	auto prepareArgs(Args... args)
	{
		std::vector<MYSQL_BIND> param_binds;
		MYSQL_BIND param = {};
		param_binds.push_back(param);
		return param_binds;
	}

private:
	MYSQL *mConn	  = nullptr;
	MYSQL_STMT *mStmt = nullptr;
	bool mHasError	= false;
};
